home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 44
/
Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso
/
Aminet
/
misc
/
emu
/
p-interp.lha
/
p-interp-0.4
/
Term.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-06-11
|
10KB
|
484 lines
/*
P-Code interpreter (to run the apple pascal system)
Copyright (C) 2000 Mario Klebsch
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
$Log: Term.c,v $
Revision 1.5 2001/06/07 20:03:10 mario
Anfang der Integration von Amiga-Patches, die Stefan A. Haubenthal
<polluks@web.de> mir geschickt hat. Es ist aber erst der Ausgabe-Teil
fertig, die Anpassungen der Eingaberoutinen sind daher noch nicht
integriert.
Revision 1.4 2001/05/26 15:13:29 mario
Diverse kleine Fehler behoben, fehlende #includes, Labels ohne Statement
dahinter, ...
Revision 1.3 2001/05/20 20:14:40 mario
Neues Gerät PRINTER: implementiert
Revision 1.2 2001/05/20 13:12:02 mario
CVS-Idents und Logs eingefügt
*/
#ident "$Id: Term.c,v 1.5 2001/06/07 20:03:10 mario Exp $";
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#ifndef _AMIGA
#include <curses.h>
#include <term.h>
#include <termios.h>
#include <assert.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif
#include "psystem.h"
#include "Memory.h"
#include "Term.h"
static int BatchMode=0;
static int TermIn=-1;
static int TermOut=-1;
#ifndef _AMIGA
struct termios OldTerm;
#else
static char *clr_eol = "\x9bK";
static char *clr_eos = "\x9bJ";
static char *clear_screen = "\x9b""2J";
static char *insert_line = "\x9bL";
static char *cursor_home = "\x9bH";
static char *cursor_up = "\x9b""A";
static char *cursor_right = "\x9b""C";
static char *cursor_address = "\x9b%d;%dH";
#define tgoto(cursor_address, x, y) s="",sprintf(s, cursor_address, y+1, x+1)
#endif /* _AMIGA */
/*
erase line=0
erase to end of screen=11
erase screen=12
insert line=22
move cursor home=25
move cursor right=28
erase to end of line=29
gotoxy=30
move cursor up=31
*/
void TermWrite(char ch, word Mode)
{
static int state=0;
static int x;
int y;
char *s;
switch(state)
{
case 0:
switch(ch)
{
case 0: /* erase line ??? */
if (!(Mode&0x8))
;
else
write(TermOut, &ch, 1);
break;
case 7:
if (!BatchMode)
write(TermOut, &ch, 1);
break;
case 11: /* erase to end of screen */
if (!BatchMode && clr_eos)
write(TermOut, clr_eos, strlen(clr_eos));
break;
case 12: /* erase screen */
if (!BatchMode && clear_screen)
write(TermOut, clear_screen, strlen(clear_screen));
break;
case 13: /* carriage return */
if (!(Mode&0x4))
if (!BatchMode)
write(TermOut,"\r\n", 2);
else
write(TermOut,"\n", 1);
else
write(TermOut, &ch, 1);
break;
case 16: /* DLE prefix */
if (!(Mode&0x8))
state=3;
break;
case 22:
if (!BatchMode && insert_line)
write(TermOut, insert_line, strlen(insert_line));
break;
case 25: /* move cursor home */
if (!BatchMode && cursor_home)
write(TermOut, cursor_home, strlen(cursor_home));
else
write(TermOut,"\n", 1);
break;
case 28: /* move cursor right */
if (!BatchMode && cursor_right)
write(TermOut, cursor_right, strlen(cursor_right));
break;
case 29: /* erase to end of line */
if (!BatchMode && clr_eol)
write(TermOut, clr_eol, strlen(clr_eol));
break;
case 30: /* gotoxy */
state=1;
break;
case 31: /* move cursor up */
if (!BatchMode && cursor_up)
write(TermOut, cursor_up, strlen(cursor_up));
break;
default:
write(TermOut, &ch, 1);
break;
}
break;
case 1:
x=ch-' ';
state=2;
break;
case 2: /* gotoxy complete */
y=ch-' ';
if (!BatchMode && cursor_address)
{
s=tgoto(cursor_address, x, y);
write(TermOut, s, strlen(s));
}
state=0;
break;
case 3: /* char after DLE */
ch -= 0x20;
while (ch--)
write(TermOut, " ", 1);
state=0;
break;
}
}
#ifndef _AMIGA
static struct translator
{
struct translator *Next;
char *Pattern;
byte Key;
void (*Action)(byte);
} *Keys=NULL;
static void AddKeyTranslation(byte Key, char *Pattern, void (*Action)(byte))
{
struct translator *NewKey=malloc(sizeof(struct translator));
assert(NewKey);
NewKey->Key = Key;
NewKey->Pattern = Pattern;
NewKey->Action = Action;
NewKey->Next = Keys;
Keys=NewKey;
}
char TermRead(void)
{
unsigned char ch;
static int state=0;
static int BufIdx=0;
static char Buffer[10];
if (state==0)
while (1)
{
fd_set fds;
struct timeval tv;
FD_ZERO(&fds);
FD_SET(TermIn, &fds);
tv.tv_sec = 0;
tv.tv_usec = 25000;
if (select(TermIn+1, &fds, NULL, NULL, BufIdx?&tv:NULL)>0)
{ /* Ein Zeichen ist verfügbar */
struct translator *t;
int Match=0;
if (read(TermIn, &ch, 1)<1) /* Lesen und in Puffer speichern */
if (BatchMode)
exit(0);
#ifndef XXX
if (ch=='\0') /* XXX Quick-Hack :-( */
continue;
#endif
Buffer[BufIdx++]=ch;
for (t=Keys; t; t=t->Next)
{
int i;
for (i=0; i< BufIdx; i++)
if (Buffer[i] != t->Pattern[i])
goto next;
if (!(t->Pattern[BufIdx])) /* full Pattern match */
{
BufIdx=0;
return (t->Key);
}
Match=1;
break;
next:
;
}
if (!Match)
goto ret;
}
else /* Timeout */
{
ret:
if (BufIdx>1)
state=1;
else
BufIdx=0;
return(Buffer[0]);
}
}
else
{
ch=Buffer[state++];
if (state >=BufIdx)
{
state=0;
BufIdx=0;
}
return(ch);
}
}
int TermStat(void)
{
fd_set fds;
struct timeval tv;
FD_ZERO(&fds);
FD_SET(TermIn, &fds);
tv.tv_sec = 0;
tv.tv_usec = 0;
if (select(TermIn+1, &fds, NULL, NULL, &tv)>0)
return(1);
else
return(0);
}
static void OpenXTerm(void)
{
int i;
int s;
struct sockaddr_in addr;
char Buffer[256];
unsigned char TelnetInit[]=
{ 255, 253, 3,
255, 251, 3,
255, 251, 1
};
if ((s=socket(PF_INET, SOCK_STREAM, 0))<0)
{
perror("socket()");
exit(1);
}
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
addr.sin_port=htons(0);
if (bind(s, (struct sockaddr*)&addr, sizeof(addr))<0)
{
perror("bind()");
exit(1);
}
if (listen(s,1)<0)
{
perror("listen()");
exit(1);
}
i=sizeof(addr);
if (getsockname(s, (struct sockaddr*)&addr, &i)<0)
{
perror("getsockname()");
exit(1);
}
snprintf(Buffer, sizeof(Buffer), "xterm -geometry 80x24 -e "
"telnet -E localhost %d&", ntohs(addr.sin_port));
system(Buffer);
i=sizeof(addr);
if ((TermOut=accept(s, (struct sockaddr*)&addr, &i))<0)
{
perror("accept()");
exit(1);
}
close(s);
write(TermOut, TelnetInit, sizeof(TelnetInit));
for (i=0; i<sizeof(TelnetInit); i++)
read(TermOut, &s, 1);
}
void TermOpen(int UseXTerm, int BatchFd)
{
struct termios NewTerm;
if (BatchFd<0)
BatchMode=0;
else
{
BatchMode=1;
TermIn=BatchFd;
}
if (UseXTerm)
{
OpenXTerm();
setupterm("xterm", TermOut, NULL);
}
else
{
if (BatchMode)
{
TermOut=1;
setupterm("dumb", TermOut, NULL);
}
else
{
if ((TermOut=open("/dev/tty", O_RDWR))<0)
{
perror("/dev/tty");
exit(1);
}
setupterm(NULL, TermOut, NULL);
}
}
if (TermIn<0)
TermIn=TermOut;
if (BatchMode)
{
AddKeyTranslation('\r', "\n", NULL);
}
else
{
tcgetattr(TermOut, &OldTerm);
NewTerm=OldTerm;
NewTerm.c_iflag &= ~(PARMRK | ISTRIP | INLCR | IGNCR |
ICRNL | IUCLC | IXOFF | IXON);
NewTerm.c_oflag &= ~OPOST;
NewTerm.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL | IEXTEN);
NewTerm.c_cc[VMIN]=1;
NewTerm.c_cc[VTIME]=0;
tcsetattr(TermOut, TCSANOW, &NewTerm);
if (init_1string)
write(TermOut, init_1string, strlen(init_1string));
if (init_2string)
write(TermOut, init_2string, strlen(init_2string));
if (init_3string)
write(TermOut, init_3string, strlen(init_3string));
if (enter_ca_mode)
write(TermOut, enter_ca_mode, strlen(enter_ca_mode));
AddKeyTranslation(0x0b, "\033[A", NULL);
AddKeyTranslation(0x0a, "\033[B", NULL);
AddKeyTranslation(0x15, "\033[C", NULL);
AddKeyTranslation(0x08, "\033[D", NULL);
AddKeyTranslation(0x0b, "\033[OA", NULL);
AddKeyTranslation(0x0a, "\033[OB", NULL);
AddKeyTranslation(0x15, "\033[OC", NULL);
AddKeyTranslation(0x08, "\033[OD", NULL);
if (key_up)
AddKeyTranslation(0x0b, key_up, NULL);
if (key_down)
AddKeyTranslation(0x0a, key_down, NULL);
if (key_right)
AddKeyTranslation(0x15, key_right, NULL);
if (key_left)
AddKeyTranslation(0x08, key_left, NULL);
}
}
void TermClose(void)
{
if (!BatchMode)
{
write(TermOut,"\r\n",2);
if (exit_ca_mode)
write(TermOut, exit_ca_mode, strlen(exit_ca_mode));
if (reset_1string)
write(TermOut, reset_1string, strlen(reset_1string));
if (reset_2string)
write(TermOut, reset_2string, strlen(reset_2string));
if (reset_3string)
write(TermOut, reset_3string, strlen(reset_3string));
tcsetattr(TermOut, TCSANOW, &OldTerm);
}
else
write(TermOut,"\n",1);
close(TermOut);
close(TermIn);
}
#else
void TermOpen(int UseXTerm, int BatchFd)
{
TermIn=0;
TermOut=1;
rawcon(1);
}
void TermClose(void)
{
rawcon(0);
}
char TermRead(void)
{
signed char ch;
read(TermIn, &ch, 1);
return ch;
}
int TermStat(void)
{
return WaitForChar(Input(),1);
}
#endif